package com.dongdongqiang.daogenerator.tablemetabuilder;

import com.dongdongqiang.daogenerator.pojo.TableColumn;
import com.dongdongqiang.daogenerator.pojo.TableMeta;
import com.dongdongqiang.daogenerator.utils.Misc;
import com.dongdongqiang.daogenerator.utils.POJOUtils;
import com.dongdongqiang.daogenerator.utils.ReflectionUtils;

import javax.persistence.Table;
import java.lang.reflect.Field;
import java.util.ArrayList;
import java.util.List;

/**
 * 实体工具类
 * Created by ZZB on 2017/9/25.
 */
public class TableMetaBuilderImpl implements TableMetaBuilder {
    private TableColumnBuilder tableColumnBuilder;

    public TableMetaBuilderImpl(TableColumnBuilder tableColumnBuilder) {
        this.tableColumnBuilder = tableColumnBuilder;
    }

    public <T> TableMeta obtainByObject(T o) {
        TableMeta tableMeta = new TableMeta();
        Class aClazz = o.getClass();
        return obtainByClass(aClazz);
    }

    public TableMeta obtainByClass(Class clazz) {
        if (TableMetaContext.exist(clazz))
            return TableMetaContext.obtainByClazz(clazz);
        TableMeta tableMeta = new TableMeta();
        tableMeta.setBeanClass(clazz);
        {
            //tableName
            Table table = (Table) clazz.getAnnotation(Table.class);
            String tableName;
            if (table != null) {
                tableName = table.name();
            } else {
                tableName = Misc.camelToUnderline(clazz.getSimpleName());
            }
            tableMeta.setTableName(tableName);
        }
        {
            //beanName
            String beanName = clazz.getSimpleName();
            tableMeta.setBeanName(beanName);
        }

        Field[] fields = ReflectionUtils.getAllDeclaredFields(clazz);
        {
            //tableColumns
            List<TableColumn> tableColumns = new ArrayList<>();
            for (Field declaredField : fields) {
                TableColumn tableColumn = tableColumnBuilder.obtainByField(declaredField);
                tableColumns.add(tableColumn);
                if (tableColumn.getPrimaryKey()) {
                    tableMeta.setPrimaryKeyColumn(tableColumn);
                }
            }
            tableMeta.setTableColumns(tableColumns);
        }
        {
            //put into cache
            TableMetaContext.put(tableMeta);
        }
        return tableMeta;
    }

    public Object readFieldByColumnName(Object object, String columnName) throws Exception {
        Class clazz = object.getClass();
        TableColumn tableColumn = TableMetaContext.obtainByColumnName(clazz, columnName);
        return POJOUtils.readDeclaredFieldByGetMethod(object, tableColumn.getPropertyName());
    }

    public TableColumn obtainByColumnName(Class clazz, String columnName) {
        return TableMetaContext.obtainByColumnName(clazz, columnName);
    }

    public TableColumn obtainByFieldName(Class clazz, String fieldName) {
        return TableMetaContext.obtainByFieldName(clazz, fieldName);
    }

}
